package com.xbongbong.saas.help.workflow;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ProductConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.CostAdjustProductEntity;
import com.xbongbong.saas.domain.entity.InstockProductEntity;
import com.xbongbong.saas.domain.entity.OutstockProductEntity;
import com.xbongbong.saas.domain.entity.ProductSerialBalanceEntity;
import com.xbongbong.saas.domain.entity.ProductSerialFlowEntity;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.InstockTypeEnum;
import com.xbongbong.saas.enums.OutstockTypeEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.StockTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractOutstockEnum;
import com.xbongbong.saas.enums.business.InstockEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.PurchaseInstockEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.RefundInstockEnum;
import com.xbongbong.saas.enums.business.ReturnedPurchaseEnum;
import com.xbongbong.saas.enums.business.ReturnedPurchaseOutstockEnum;
import com.xbongbong.saas.enums.business.SerialEnum;
import com.xbongbong.saas.enums.business.SerialStatusEnum;
import com.xbongbong.saas.help.SaveFormatHelp;
import com.xbongbong.saas.model.InstockProductModel;
import com.xbongbong.saas.model.OutstockProductModel;
import com.xbongbong.saas.model.ProductSerialBalanceModel;
import com.xbongbong.saas.model.ProductSerialFlowModel;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 *
 * @author 魏荣杰
 *
 */
@Component
public class ProductSerialHelp {

    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private InstockProductModel instockProductModel;
    @Resource
    private OutstockProductModel outstockProductModel;
    @Resource
    private ProductSerialBalanceModel productSerialBalanceModel;
    @Resource
    private ProductSerialFlowModel productSerialFlowModel;

    //需要录入序列号单据
    private static final List<Integer> entrySeqForm = Arrays.asList(XbbRefTypeEnum.PURCHASE_INSTOCK.getCode(), XbbRefTypeEnum.ORI_STOCK.getCode(), XbbRefTypeEnum.PRODUCTION_INSTOCK.getCode());
    // 需要选择序列号单据
    private static final List<Integer> selectSeqForm = Arrays.asList(XbbRefTypeEnum.RETURNED_MATERIEL_INSTOCK.getCode(), XbbRefTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode(), XbbRefTypeEnum.REFUND_INSTOCK.getCode(), XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode(), XbbRefTypeEnum.PRODUCTION_MATERIEL_OUTSTOCK.getCode(), XbbRefTypeEnum.WORK_ORDER_OUTSTOCK.getCode(), XbbRefTypeEnum.TRANSFER.getCode());


    /**
     * 序列号出入库表保存
     *
     * @param corpid  公司id
     * @param businessType
     * @param data  出入库单数据
     * @param dataId 数据id
     * @param serialNo 流水号
     * @param productStr 产品信息
     * @throws XbbException 异常
     */
    public void saveSerial(String corpid, Integer businessType, JSONObject data, Long dataId, String serialNo, String productStr) throws XbbException {
        // 未开启序列号
        CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.ENABLE_SEQ_MANAGEMENT.getAlias(), corpid);
        if (Objects.isNull(companyConfigEntity) || Objects.equals(companyConfigEntity.getConfigValue(), "0")) {
            return;
        }

        // 其他出入库单区分出入库类型
        InstockTypeEnum instockTypeEnum = null;
        OutstockTypeEnum outstockTypeEnum = null;
        if (Objects.equals(businessType, XbbRefTypeEnum.OTHER_INSTOCK.getCode())) {
            Integer type = data.getInteger(InstockEnum.TYPE.getAttr());
            instockTypeEnum = InstockTypeEnum.getByCode(type);
        } else if (Objects.equals(businessType, XbbRefTypeEnum.OTHER_OUTSTOCK.getCode())) {
            Integer type = data.getInteger(OutstockEnum.TYPE.getAttr());
            outstockTypeEnum = OutstockTypeEnum.getByCode(type);
        }
        // 出入库单关联产品数据
        JSONArray productArray = JSON.parseArray(productStr);
        if (Objects.isNull(productArray) || productArray.isEmpty()) {
            return;
        }
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        int status = 0;
        // 标识出入库业务；入库插入结存记录，出库更新结存记录
        Integer stockType = null;
        List<InstockProductEntity> instockProductEntities = new ArrayList<>();
        List<OutstockProductEntity> outstockProductEntities = new ArrayList<>();
        List<CostAdjustProductEntity> costAdjustProductEntityList = new ArrayList<>();
        switch (xbbRefTypeEnum) {
            case INSTOCK:
            case PURCHASE_INSTOCK:
            case REFUND_INSTOCK:
            case OTHER_INSTOCK:
            case PRODUCTION_INSTOCK:
            case RETURNED_MATERIEL_INSTOCK:
                status = SerialStatusEnum.IN_STOCK.getCode();
                stockType = StockTypeEnum.IN_STOCK.getCode();
                instockProductEntities = instockProductModel.getProductsByInstockIdIn(corpid, Collections.singletonList(dataId));
                break;
            case OUTSTOCK:
            case CONTRACT_OUTSTOCK:
            case OTHER_OUTSTOCK:
            case RETURNED_PURCHASE_OUTSTOCK:
            case WORK_ORDER_OUTSTOCK:
            case PRODUCTION_MATERIEL_OUTSTOCK:
                status = SerialStatusEnum.OUT_STOCK.getCode();
                stockType = StockTypeEnum.OUT_STOCK.getCode();
                outstockProductEntities = outstockProductModel.getProductsByOutstockIdIn(corpid, Collections.singletonList(dataId));
                break;
            default:
                break;
        }
        List<ProductSerialFlowEntity> productSerialFlowEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<ProductSerialBalanceEntity> productSerialBalanceList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Set<String> seqKeyList = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, ProductSerialFlowEntity> productSerialFlowEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        long now = DateTimeUtil.getInt();
        // 往来单位
        String supplierIdAttr = null;
        String supplierNameAttr = null;
        String customerIdAttr = null;
        String customerNameAttr = null;
        if (Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INSTOCK.getCode())) {
            supplierIdAttr = PurchaseInstockEnum.SUPPLIER_ID.getAttr();
            supplierNameAttr = PurchaseInstockEnum.SUPPLIER_ID_LINKED_TEXT.getAttr();
        } else if (Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE.getCode())) {
            supplierIdAttr = ReturnedPurchaseEnum.SUPPLIER_ID.getAttr();
            supplierNameAttr = ReturnedPurchaseEnum.LINK_SUPPLIER.getAttr();
        } else if (Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode())) {
            supplierIdAttr = ReturnedPurchaseOutstockEnum.LINK_SUPPLIER.getAttr();
            supplierNameAttr = ReturnedPurchaseOutstockEnum.LINK_SUPPLIER_HIDE.getAttr();
        } else if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode())) {
            customerIdAttr = ContractOutstockEnum.LINK_CUSTOMER.getAttr();
            customerNameAttr = ContractOutstockEnum.LINK_CUSTOMER_HIDE.getAttr();
        } else if (Objects.equals(businessType, XbbRefTypeEnum.REFUND.getCode())) {
            customerIdAttr = RefundEnum.CUSTOMER_ID.getAttr();
            customerNameAttr = RefundEnum.CUSTOMER_ID_LINKED_TEXT.getAttr();
        } else if (Objects.equals(businessType, XbbRefTypeEnum.REFUND_INSTOCK.getCode())) {
            customerIdAttr = RefundInstockEnum.CUSTOMER_ID.getAttr();
            customerNameAttr = RefundInstockEnum.CUSTOMER_ID_LINKED_TEXT.getAttr();
        }
        for (int i = 0; i < productArray.size(); i++) {
            JSONObject productData = productArray.getJSONObject(i);
            Long productId = productData.getLong(SelectProductEnum.PRODUCT.getAttr());
            JSONArray seqArray = productData.getJSONArray(ProductConstant.SEQ);
            if (BasicConstant.ZERO.equals(productData.getIntValue(ProductEnum.ENABLE_SERIAL_NUMBER.getSaasAttr())) || (Objects.isNull(seqArray) || seqArray.isEmpty())) {
                continue;
            }
            for (int j = 0; j < seqArray.size(); j++) {
                JSONObject seqData = seqArray.getJSONObject(j);
                String serial = seqData.getString(SerialEnum.SERIAL.getAttr());
                ProductSerialFlowEntity productSerialFlowEntity = new ProductSerialFlowEntity();
                productSerialFlowEntity.setCorpid(corpid);
                productSerialFlowEntity.setProductId(productId);
                productSerialFlowEntity.setSeq(serial);
                productSerialFlowEntity.setMemo(seqData.getString(SerialEnum.MEMO.getAttr()));
                productSerialFlowEntity.setStatus(status);
                productSerialFlowEntity.setDate(now);
                productSerialFlowEntity.setBusinessType(businessType);
                productSerialFlowEntity.setRefId(dataId);
                productSerialFlowEntity.setRefSheetNo(serialNo);
                // 关联产品id
                if (StockTypeEnum.IN_STOCK.getCode().equals(stockType) && CollectionUtils.isNotEmpty(instockProductEntities)) {
                    InstockProductEntity instockProductEntity = instockProductEntities.get(i);
                    productSerialFlowEntity.setRefProductId(instockProductEntity.getId());
                    productSerialFlowEntity.setParentId(instockProductEntity.getParentId());
                } else if (StockTypeEnum.OUT_STOCK.getCode().equals(stockType) && CollectionUtils.isNotEmpty(outstockProductEntities)) {
                    OutstockProductEntity outstockProductEntity = outstockProductEntities.get(i);
                    productSerialFlowEntity.setRefProductId(outstockProductEntity.getId());
                    productSerialFlowEntity.setParentId(outstockProductEntity.getParentId());
                }
                SaveFormatHelp.formatLinkBusiness4Save(productData, SelectProductEnum.WAREHOUSE.getAttr(), "warehouseName", FieldTypeEnum.LINK_BUSINESS_SINGLE.getType());
                productSerialFlowEntity.setWarehouseId(productData.getLong(SelectProductEnum.WAREHOUSE.getAttr()));
                productSerialFlowEntity.setWarehouseName(productData.getString("warehouseName"));
                // 往来单位
                if (Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INSTOCK.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode())) {
                    productSerialFlowEntity.setBusinessId(data.getLong(supplierIdAttr));
                    productSerialFlowEntity.setBusinessName(data.getString(supplierNameAttr));
                } else if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.REFUND.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.REFUND_INSTOCK.getCode())) {
                    productSerialFlowEntity.setBusinessId(data.getLong(customerIdAttr));
                    productSerialFlowEntity.setBusinessName(data.getString(customerNameAttr));
                }
                productSerialFlowEntity.setSeqKey(productId + "_" + serial);
                productSerialFlowEntity.setDel(BasicConstant.ZERO);

                seqKeyList.add(productSerialFlowEntity.getSeqKey());
                productSerialFlowEntityList.add(productSerialFlowEntity);
                productSerialFlowEntityMap.put(productSerialFlowEntity.getSeqKey(), productSerialFlowEntity);
            }
        }


        if (CollectionUtils.isNotEmpty(productSerialFlowEntityList)) {
            if (entrySeqForm.contains(businessType) || Objects.equals(instockTypeEnum, InstockTypeEnum.OTHER_INSTOCK) || Objects.equals(instockTypeEnum, InstockTypeEnum.ASSEMBLE_INSTOCK) || Objects.equals(instockTypeEnum, InstockTypeEnum.INVENTORY_INSTOCK)) {
                for (ProductSerialFlowEntity entity : productSerialFlowEntityList) {
                    ProductSerialBalanceEntity productSerialBalanceEntity = new ProductSerialBalanceEntity(entity);
                    productSerialBalanceList.add(productSerialBalanceEntity);
                }
                if (CollectionUtils.isNotEmpty(productSerialBalanceList)) {
                    productSerialBalanceModel.insertBatch(productSerialBalanceList);
                }
            } else if (selectSeqForm.contains(businessType) || Objects.equals(outstockTypeEnum, OutstockTypeEnum.OTHER_OUTSTOCK) || Objects.equals(outstockTypeEnum, OutstockTypeEnum.ASSEMBLE_OUTSTOCK) || Objects.equals(outstockTypeEnum, OutstockTypeEnum.INVENTORY_OUTSTOCK) || Objects.equals(outstockTypeEnum, OutstockTypeEnum.TRANSFER_OUTSTOCK) || Objects.equals(instockTypeEnum, InstockTypeEnum.TRANSFER_INSTOCK)) {
                Map<String, Object> param = new HashMap<>();
                param.put("corpid", corpid);
                param.put("seqKeyIn", seqKeyList);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                List<ProductSerialBalanceEntity> entitys = productSerialBalanceModel.findEntitys(param);
                for (ProductSerialBalanceEntity entity : entitys) {
                    ProductSerialFlowEntity productSerialFlowEntity = productSerialFlowEntityMap.get(entity.getSeqKey());
                    entity.setStatus(productSerialFlowEntity.getStatus());
                    entity.setBusinessType(productSerialFlowEntity.getBusinessType());
                    entity.setRefId(productSerialFlowEntity.getRefId());
                    entity.setRefSheetNo(productSerialFlowEntity.getRefSheetNo());
                    entity.setRefProductId(productSerialFlowEntity.getRefProductId());
                    entity.setDate(productSerialFlowEntity.getDate());
                    entity.setBusinessId(productSerialFlowEntity.getBusinessId());
                    entity.setWarehouseId(productSerialFlowEntity.getWarehouseId());
                    entity.setBusinessName(productSerialFlowEntity.getBusinessName());
                }
                productSerialBalanceModel.updateBatch(entitys, corpid);
            }
            productSerialFlowModel.insertBatch(productSerialFlowEntityList);
        }
    }

    /**
     * 序列号出入库表保存
     *
     * @param corpid  公司id
     * @param businessType
     * @param data  出入库单数据
     * @param dataId 数据id
     * @param serialNo 流水号
     * @param productMap 产品信息 {关联产品id: {"seq": [{SerialEnum.SERIAL.getAttr(): "", SerialEnum.MEMO.getAttr(): ""}, "": ""]}}
     * @throws XbbException 异常
     */
    public void saveSerial(String corpid, Integer businessType, JSONObject data, Long dataId, String serialNo, Map<Long, JSONObject> productMap) throws XbbException {
        // 未开启序列号
        CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.ENABLE_SEQ_MANAGEMENT.getAlias(), corpid);
        if (Objects.isNull(companyConfigEntity) || Objects.equals(companyConfigEntity.getConfigValue(), "0")) {
            return;
        }

        // 其他出入库单区分出入库类型
        InstockTypeEnum instockTypeEnum = null;
        OutstockTypeEnum outstockTypeEnum = null;
        if (Objects.equals(businessType, XbbRefTypeEnum.OTHER_INSTOCK.getCode())) {
            Integer type = data.getInteger(InstockEnum.TYPE.getAttr());
            instockTypeEnum = InstockTypeEnum.getByCode(type);
        } else if (Objects.equals(businessType, XbbRefTypeEnum.OTHER_OUTSTOCK.getCode())) {
            Integer type = data.getInteger(OutstockEnum.TYPE.getAttr());
            outstockTypeEnum = OutstockTypeEnum.getByCode(type);
        }
        // 出入库单关联产品数据
        if (Objects.isNull(productMap) || productMap.isEmpty()) {
            return;
        }
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        int status = 0;
        // 标识出入库业务；入库插入结存记录，出库更新结存记录
        Integer stockType = null;
        Map<Long, InstockProductEntity> instockProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, OutstockProductEntity> outstockProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        switch (xbbRefTypeEnum) {
            case INSTOCK:
            case PURCHASE_INSTOCK:
            case REFUND_INSTOCK:
            case OTHER_INSTOCK:
            case PRODUCTION_INSTOCK:
            case RETURNED_MATERIEL_INSTOCK:
                status = SerialStatusEnum.IN_STOCK.getCode();
                stockType = StockTypeEnum.IN_STOCK.getCode();
                List<InstockProductEntity> instockProductEntities = instockProductModel.getProductsByInstockIdIn(corpid, Collections.singletonList(dataId));
                instockProductEntities.forEach(item->{
                    instockProductMap.put(item.getId(), item);
                });
                break;
            case OUTSTOCK:
            case CONTRACT_OUTSTOCK:
            case OTHER_OUTSTOCK:
            case RETURNED_PURCHASE_OUTSTOCK:
            case WORK_ORDER_OUTSTOCK:
            case PRODUCTION_MATERIEL_OUTSTOCK:
                status = SerialStatusEnum.OUT_STOCK.getCode();
                stockType = StockTypeEnum.OUT_STOCK.getCode();
                List<OutstockProductEntity> outstockProductEntities = outstockProductModel.getProductsByOutstockIdIn(corpid, Collections.singletonList(dataId));
                outstockProductEntities.forEach(item->{
                    outstockProductMap.put(item.getId(), item);
                });
                break;
            default:
                break;
        }
        List<ProductSerialFlowEntity> productSerialFlowEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<ProductSerialBalanceEntity> productSerialBalanceList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Set<String> seqKeyList = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, ProductSerialFlowEntity> productSerialFlowEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        long now = DateTimeUtil.getInt();
        // 往来单位
        String supplierIdAttr = null;
        String supplierNameAttr = null;
        String customerIdAttr = null;
        String customerNameAttr = null;
        if (Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INSTOCK.getCode())) {
            supplierIdAttr = PurchaseInstockEnum.SUPPLIER_ID.getAttr();
            supplierNameAttr = PurchaseInstockEnum.SUPPLIER_ID_LINKED_TEXT.getAttr();
        } else if (Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE.getCode())) {
            supplierIdAttr = ReturnedPurchaseEnum.SUPPLIER_ID.getAttr();
            supplierNameAttr = ReturnedPurchaseEnum.LINK_SUPPLIER.getAttr();
        } else if (Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode())) {
            supplierIdAttr = ReturnedPurchaseOutstockEnum.LINK_SUPPLIER.getAttr();
            supplierNameAttr = ReturnedPurchaseOutstockEnum.LINK_SUPPLIER_HIDE.getAttr();
        } else if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode())) {
            customerIdAttr = ContractOutstockEnum.LINK_CUSTOMER.getAttr();
            customerNameAttr = ContractOutstockEnum.LINK_CUSTOMER_HIDE.getAttr();
        } else if (Objects.equals(businessType, XbbRefTypeEnum.REFUND.getCode())) {
            customerIdAttr = RefundEnum.CUSTOMER_ID.getAttr();
            customerNameAttr = RefundEnum.CUSTOMER_ID_LINKED_TEXT.getAttr();
        } else if (Objects.equals(businessType, XbbRefTypeEnum.REFUND_INSTOCK.getCode())) {
            customerIdAttr = RefundInstockEnum.CUSTOMER_ID.getAttr();
            customerNameAttr = RefundInstockEnum.CUSTOMER_ID_LINKED_TEXT.getAttr();
        }
        Iterator<Long> iterator = productMap.keySet().iterator();
        while (iterator.hasNext()) {
            Long key = iterator.next();
            JSONObject productData = productMap.get(key);
            Long productId = productData.getLong(SelectProductEnum.PRODUCT.getAttr());
            JSONArray seqArray = productData.getJSONArray(ProductConstant.SEQ);
            if (BasicConstant.ZERO.equals(productData.getIntValue(ProductEnum.ENABLE_SERIAL_NUMBER.getSaasAttr())) || (Objects.isNull(seqArray) || seqArray.isEmpty())) {
                continue;
            }
            for (int j = 0; j < seqArray.size(); j++) {
                JSONObject seqData = seqArray.getJSONObject(j);
                String serial = seqData.getString(SerialEnum.SERIAL.getAttr());
                ProductSerialFlowEntity productSerialFlowEntity = new ProductSerialFlowEntity();
                productSerialFlowEntity.setCorpid(corpid);
                productSerialFlowEntity.setProductId(productId);
                productSerialFlowEntity.setSeq(serial);
                productSerialFlowEntity.setStatus(status);
                productSerialFlowEntity.setMemo(seqData.getString(SerialEnum.MEMO.getAttr()));
                productSerialFlowEntity.setDate(now);
                productSerialFlowEntity.setBusinessType(businessType);
                productSerialFlowEntity.setRefId(dataId);
                productSerialFlowEntity.setRefSheetNo(serialNo);
                // 关联产品id
                if (StockTypeEnum.IN_STOCK.getCode().equals(stockType) && !instockProductMap.isEmpty()) {
                    InstockProductEntity instockProductEntity = instockProductMap.get(key);
                    productSerialFlowEntity.setRefProductId(instockProductEntity.getId());
                    productSerialFlowEntity.setParentId(instockProductEntity.getParentId());
                } else if (StockTypeEnum.OUT_STOCK.getCode().equals(stockType) && !outstockProductMap.isEmpty()) {
                    OutstockProductEntity outstockProductEntity = outstockProductMap.get(key);
                    productSerialFlowEntity.setRefProductId(outstockProductEntity.getId());
                    productSerialFlowEntity.setParentId(outstockProductEntity.getParentId());
                }
                SaveFormatHelp.formatLinkBusiness4Save(productData, SelectProductEnum.WAREHOUSE.getAttr(), "warehouseName", FieldTypeEnum.LINK_BUSINESS_SINGLE.getType());
                productSerialFlowEntity.setWarehouseName(productData.getString("warehouseName"));
                productSerialFlowEntity.setWarehouseId(productData.getLong(SelectProductEnum.WAREHOUSE.getAttr()));
                // 往来单位
                if (Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INSTOCK.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode())) {
                    productSerialFlowEntity.setBusinessId(data.getLong(supplierIdAttr));
                    productSerialFlowEntity.setBusinessName(data.getString(supplierNameAttr));
                } else if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.REFUND.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.REFUND_INSTOCK.getCode())) {
                    productSerialFlowEntity.setBusinessId(data.getLong(customerIdAttr));
                    productSerialFlowEntity.setBusinessName(data.getString(customerNameAttr));
                }
                productSerialFlowEntity.setDel(BasicConstant.ZERO);
                productSerialFlowEntity.setSeqKey(productId + "_" + serial);

                productSerialFlowEntityList.add(productSerialFlowEntity);
                seqKeyList.add(productSerialFlowEntity.getSeqKey());
                productSerialFlowEntityMap.put(productSerialFlowEntity.getSeqKey(), productSerialFlowEntity);
            }
        }

        saveSerialFlowAndBalance(productSerialFlowEntityList, businessType, instockTypeEnum, outstockTypeEnum, productSerialFlowEntityMap, corpid, seqKeyList, productSerialBalanceList);

    }

    /**
     * 保存序列号流水表以及更新结存表
     * @param productSerialFlowEntityList
     * @param businessType
     * @param instockTypeEnum
     * @param outstockTypeEnum
     * @param productSerialFlowEntityMap
     * @param corpid
     * @param seqKeyList
     * @param productSerialBalanceList
     * @throws XbbException
     */
    private void saveSerialFlowAndBalance(List<ProductSerialFlowEntity> productSerialFlowEntityList, Integer businessType, InstockTypeEnum instockTypeEnum, OutstockTypeEnum outstockTypeEnum, Map<String, ProductSerialFlowEntity> productSerialFlowEntityMap, String corpid, Set<String> seqKeyList, List<ProductSerialBalanceEntity> productSerialBalanceList) throws XbbException {
        if (CollectionUtils.isNotEmpty(productSerialFlowEntityList)) {
            if (entrySeqForm.contains(businessType) || Objects.equals(instockTypeEnum, InstockTypeEnum.OTHER_INSTOCK) || Objects.equals(instockTypeEnum, InstockTypeEnum.ASSEMBLE_INSTOCK) || Objects.equals(instockTypeEnum, InstockTypeEnum.INVENTORY_INSTOCK)) {
                for (ProductSerialFlowEntity entity : productSerialFlowEntityList) {
                    ProductSerialBalanceEntity productSerialBalanceEntity = new ProductSerialBalanceEntity(entity);
                    productSerialBalanceList.add(productSerialBalanceEntity);
                }
                if (CollectionUtils.isNotEmpty(productSerialBalanceList)) {
                    productSerialBalanceModel.insertBatch(productSerialBalanceList);
                }
            } else if (selectSeqForm.contains(businessType) || Objects.equals(outstockTypeEnum, OutstockTypeEnum.OTHER_OUTSTOCK) || Objects.equals(outstockTypeEnum, OutstockTypeEnum.ASSEMBLE_OUTSTOCK) || Objects.equals(outstockTypeEnum, OutstockTypeEnum.INVENTORY_OUTSTOCK) || Objects.equals(outstockTypeEnum, OutstockTypeEnum.TRANSFER_OUTSTOCK) || Objects.equals(instockTypeEnum, InstockTypeEnum.TRANSFER_INSTOCK)) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put("seqKeyIn", seqKeyList);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                List<ProductSerialBalanceEntity> entitys = productSerialBalanceModel.findEntitys(param);
                for (ProductSerialBalanceEntity entity : entitys) {
                    ProductSerialFlowEntity productSerialFlowEntity = productSerialFlowEntityMap.get(entity.getSeqKey());
                    entity.setStatus(productSerialFlowEntity.getStatus());
                    entity.setBusinessType(productSerialFlowEntity.getBusinessType());
                    entity.setRefId(productSerialFlowEntity.getRefId());
                    entity.setRefSheetNo(productSerialFlowEntity.getRefSheetNo());
                    entity.setDate(productSerialFlowEntity.getDate());
                    entity.setRefProductId(productSerialFlowEntity.getRefProductId());
                    entity.setBusinessId(productSerialFlowEntity.getBusinessId());
                    entity.setWarehouseId(productSerialFlowEntity.getWarehouseId());
                    entity.setBusinessName(productSerialFlowEntity.getBusinessName());
                }
                productSerialBalanceModel.updateBatch(entitys, corpid);
            }
            productSerialFlowModel.insertBatch(productSerialFlowEntityList);
        }
    }
}
